#ifndef BMC_TLPR_TYPES_H_
#define BMC_TLPR_TYPES_H_
/*
 * GPL
 * Free soft,no warranted
 * We are all in the mud, but some of us are looking at the stars.
 * We are not born for ourselves.
 * Author kofshower@gmail.com
 */
/**
 * @file tltypes.h
 * @Synopsis  Wrap pod types in platform and library utility toolset
 * @author Chai JunJun
 * @date 2009-06-12
 */
#include <tlpr/tlcpucfg.h>
#include <stddef.h>

/***********************************************************************
** MACROS:      TL_BEGIN_MACRO
**              TL_END_MACRO
** DESCRIPTION:
**      Macro body brackets so that macros with compound statement definitions
**      behave syntactically more like functions when called.
***********************************************************************/
#define TL_BEGIN_MACRO  do {
#define TL_END_MACRO    } while (0)

/***********************************************************************
** MACROS:      TL_BEGIN_EXTERN_C
**              TL_END_EXTERN_C
** DESCRIPTION:
**      Macro shorthands for conditional C++ extern block delimiters.
***********************************************************************/
#ifdef __cplusplus
#define TL_BEGIN_EXTERN_C       extern "C" {
#define TL_END_EXTERN_C         }
#else
#define TL_BEGIN_EXTERN_C
#define TL_END_EXTERN_C
#endif

/***********************************************************************
** MACROS:      TL_BIT
**              TL_BITMASK
** DESCRIPTION:
** Bit masking macros.  XXX n must be <= 31 to be portable
***********************************************************************/
#define TL_BIT(n)       ((TLUint32)1 << (n))
#define TL_BITMASK(n)   (TL_BIT(n) - 1)

/***********************************************************************
** MACROS:      TL_ROUNDUP
**              TL_MIN
**              TL_MAX
**              TL_ABS
** DESCRIPTION:
**      Commonly used macros for operations on compatible types.
***********************************************************************/
#define TL_ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
#define TL_MIN(x,y)     ((x)<(y)?(x):(y))
#define TL_MAX(x,y)     ((x)>(y)?(x):(y))
#define TL_ABS(x)       ((x)<0?-(x):(x))

TL_BEGIN_EXTERN_C

/************************************************************************
** TYPES:       TLUint8
**              TLInt8
** DESCRIPTION:
**  The int8 types are known to be 8 bits each. There is no type that
**      is equivalent to a plain "char".
************************************************************************/
#if TL_BYTES_PER_BYTE == 1
typedef unsigned char TLUint8;
/*
** Some cfront-based C++ compilers do not like 'signed char' and
** issue the warning message:
**     warning: "signed" not implemented (ignored)
** For these compilers, we have to define TLInt8 as plain 'char'.
** Make sure that plain 'char' is indeed signed under these compilers.
*/
#if (defined(HPUX) && defined(__cplusplus) \
        && !defined(__GNUC__) && __cplusplus < 199707L) \
    || (defined(SCO) && defined(__cplusplus) \
        && !defined(__GNUC__) && __cplusplus == 1L)
typedef char TLInt8;
#else
typedef signed char TLInt8;
#endif
#else
#error No suitable type for TLInt8/TLUint8
#endif

/************************************************************************
 * MACROS:      TL_INT8_MAX
 *              TL_INT8_MIN
 *              TL_UINT8_MAX
 * DESCRIPTION:
 *  The maximum and minimum values of a TLInt8 or TLUint8.
************************************************************************/

#define TL_INT8_MAX 127
#define TL_INT8_MIN (-128)
#define TL_UINT8_MAX 255U

/************************************************************************
** TYPES:       TLUint16
**              TLInt16
** DESCRIPTION:
**  The int16 types are known to be 16 bits each.
************************************************************************/
#if TL_BYTES_PER_SHORT == 2
typedef unsigned short TLUint16;
typedef short TLInt16;
#else
#error No suitable type for TLInt16/TLUint16
#endif

/************************************************************************
 * MACROS:      TL_INT16_MAX
 *              TL_INT16_MIN
 *              TL_UINT16_MAX
 * DESCRIPTION:
 *  The maximum and minimum values of a TLInt16 or TLUint16.
************************************************************************/

#define TL_INT16_MAX 32767
#define TL_INT16_MIN (-32768)
#define TL_UINT16_MAX 65535U

/************************************************************************
** TYPES:       TLUint32
**              TLInt32
** DESCRIPTION:
**  The int32 types are known to be 32 bits each.
************************************************************************/
#if TL_BYTES_PER_INT == 4
typedef unsigned int TLUint32;
typedef int TLInt32;
#define TL_INT32(x)  x
#define TL_UINT32(x) x ## U
#elif TL_BYTES_PER_LONG == 4
typedef unsigned long TLUint32;
typedef long TLInt32;
#define TL_INT32(x)  x ## L
#define TL_UINT32(x) x ## UL
#else
#error No suitable type for TLInt32/TLUint32
#endif

/************************************************************************
 * MACROS:      TL_INT32_MAX
 *              TL_INT32_MIN
 *              TL_UINT32_MAX
 * DESCRIPTION:
 *  The maximum and minimum values of a TLInt32 or TLUint32.
************************************************************************/

#define TL_INT32_MAX TL_INT32(2147483647)
#define TL_INT32_MIN (-TL_INT32_MAX - 1)
#define TL_UINT32_MAX TL_UINT32(4294967295)

/************************************************************************
** TYPES:       TLUint64
**              TLInt64
** DESCRIPTION:
**  The int64 types are known to be 64 bits each. Care must be used when
**      declaring variables of type TLUint64 or TLInt64. Different hardware
**      architectures and even different compilers have varying support for
**      64 bit values. The only guaranteed portability requires the use of
**      the LL_ macros (see prlong.h).
************************************************************************/
#ifdef HAVE_LONG_LONG
/*
 * On 64-bit Mac OS X, uint64 needs to be defined as unsigned long long to
 * match uint64_t, otherwise our uint64 typedef conflicts with the uint64
 * typedef in cssmconfig.h, which CoreServices.h includes indirectly.
 */
#if TL_BYTES_PER_LONG == 8 && !defined(__APPLE__)
typedef long TLInt64;
typedef unsigned long TLUint64;
#elif defined(WIN16)
typedef __int64 TLInt64;
typedef unsigned __int64 TLUint64;
#elif defined(WIN32) && !defined(__GNUC__)
typedef __int64  TLInt64;
typedef unsigned __int64 TLUint64;
#else
typedef long long TLInt64;
typedef unsigned long long TLUint64;
#endif /* TL_BYTES_PER_LONG == 8 */
#else  /* !HAVE_LONG_LONG */
typedef struct {
#ifdef IS_LITTLE_ENDIAN
    TLUint32 lo, hi;
#else
    TLUint32 hi, lo;
#endif
} TLInt64;
typedef TLInt64 TLUint64;
#endif /* !HAVE_LONG_LONG */

/************************************************************************
** TYPES:       TLFloat64
** DESCRIPTION:
**  NSTL's floating point type is always 64 bits.
************************************************************************/
typedef double          TLFloat64;

/************************************************************************
** TYPES:       TLSize
** DESCRIPTION:
**  A type for representing the size of objects.
************************************************************************/
typedef size_t TLSize;


/************************************************************************
** TYPES:       TLOffset32, TLOffset64
** DESCRIPTION:
**  A type for representing byte offsets from some location.
************************************************************************/
typedef TLInt32 TLOffset32;
typedef TLInt64 TLOffset64;

/************************************************************************
** TYPES:       TLPtrDiff
** DESCRIPTION:
**  A type for pointer difference. Variables of this type are suitable
**      for storing a pointer or pointer subtraction.
************************************************************************/
typedef ptrdiff_t TLPtrdiff;

/************************************************************************
** TYPES:       TLUptrdiff
** DESCRIPTION:
**  A type for pointer difference. Variables of this type are suitable
**      for storing a pointer or pointer sutraction.
************************************************************************/
#ifdef _WIN64
typedef unsigned __int64 TLUptrdiff;
#else
typedef unsigned long TLUptrdiff;
#endif

#ifndef __TLUNICHAR__
#define __TLUNICHAR__
#if defined(WIN32) || defined(XP_MAC)
typedef wchar_t TLUnichar;
#else
typedef TLUint16 TLUnichar;
#endif
#endif

inline TLUint32 TLRotl(TLUint32 val, TLInt32 shift)
{
    shift &= 0x1f;
    val = (val>>(0x20 - shift)) | (val << shift);
    return val;
}

inline TLUint32 TLRotr(TLUint32 val, TLInt32 shift)
{
    shift &= 0x1f;
    val = (val<<(0x20 - shift)) | (val >> shift);
    return val;
}

TL_END_EXTERN_C

#endif /*BMC_TLPR_TYPES_H_*/

